package tr.gov.tubitak.uekae.esya.api.cades.example.convert;

import junit.framework.TestCase;
import tr.gov.tubitak.uekae.esya.api.cades.example.testconstans.TestConstants;
import tr.gov.tubitak.uekae.esya.api.cades.example.validation.ValidationUtil;
import tr.gov.tubitak.uekae.esya.api.cmssignature.ISignable;
import tr.gov.tubitak.uekae.esya.api.cmssignature.SignableFile;
import tr.gov.tubitak.uekae.esya.api.cmssignature.attribute.EParameters;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.BaseSignedData;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.ESignatureType;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.Signer;
import tr.gov.tubitak.uekae.esya.api.cmssignature.validation.SignedDataValidationResult;
import tr.gov.tubitak.uekae.esya.api.cmssignature.validation.SignedData_Status;
import tr.gov.tubitak.uekae.esya.asn.util.AsnIO;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Conversion to ESA. ESA signature can not be created directly. They must be converted from other signature types.
 * Firstly run sign operations in order to create signatures to be converted. 
 * @author orcun.ertugrul
 *
 */
public class Convert  extends TestCase
{
	private String mp3File = "D:\\mp3\\yabancı\\dido\\a.mp3";
	private String movieFile = "D:\\share\\film\\Life\\Life S01E01 Challenges of Life.mkv";
	
	private String signatureofHugeFile = TestConstants.getDirectory() + "testdata/HugeExternalContent.p7s";
	private String signatureofSmallFile = TestConstants.getDirectory() +  "testdata/SmallExternalContent.p7s";
	
	/**
	 * Converting BES signature to ESA
	 * @throws Exception
	 */
	public void testConvertBES_1() throws Exception
	{
		byte [] signatureFile = AsnIO.dosyadanOKU(TestConstants.getDirectory() + "testdata/BES-1.p7s");
		
		BaseSignedData bs = new BaseSignedData(signatureFile);
		
		Map<String,Object> parameters = new HashMap<String, Object>();
		
		//Time stamp will be needed.
		parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
		
		parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		
		bs.getSignerList().get(0).convert(ESignatureType.TYPE_EST, parameters);
		
		AsnIO.dosyayaz(bs.getEncoded(), TestConstants.getDirectory() + "testdata/EST-Converted.p7s");

		SignedDataValidationResult sdvr = ValidationUtil.validate(bs.getEncoded(), null);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	
	/**
	 * Converting BES signature to ESA
	 * @throws Exception
	 */
	public void testConvertEST() throws Exception
	{
		byte [] signatureFile = AsnIO.dosyadanOKU(TestConstants.getDirectory() + "testdata/EST-Converted.p7s");
		
		BaseSignedData bs = new BaseSignedData(signatureFile);
		
		Map<String,Object> parameters = new HashMap<String, Object>();
		
		//Time stamp will be needed.
		parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
		
		parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		
		bs.getSignerList().get(0).convert(ESignatureType.TYPE_ESXLong, parameters);
		
		AsnIO.dosyayaz(bs.getEncoded(), TestConstants.getDirectory() + "testdata/XLONG-Converted.p7s");

		SignedDataValidationResult sdvr = ValidationUtil.validate(bs.getEncoded(), null);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	/**
	 * Converting XLong signature to ESA.
	 * @throws Exception
	 */
	public void testConvertExternalXLong_2() throws Exception
	{
		byte [] signatureFile = AsnIO.dosyadanOKU(TestConstants.getDirectory() +  "testdata/ESXLong-1.p7s");
		BaseSignedData bs = new BaseSignedData(signatureFile);
		
		Map<String,Object> parameters = new HashMap<String, Object>();
		
		//Archive time stamp is added to signature, so time stamp settings are needed.
		parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
		parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		
		bs.getSignerList().get(0).convert(ESignatureType.TYPE_ESA, parameters);
		
		AsnIO.dosyayaz(bs.getEncoded(), TestConstants.getDirectory() + "testdata/ESA-Converted-1.p7s");
		
		SignedDataValidationResult sdvr = ValidationUtil.validate(bs.getEncoded(), null);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	/**
	 * Converting external signature to ESA.
	 * @throws Exception
	 */
	public void testConvertExternalContentSignature_3() throws Exception
	{
		File file = new File(mp3File);
		ISignable signable = new SignableFile(file,2048);
		
		byte [] content = AsnIO.dosyadanOKU(signatureofSmallFile);
		BaseSignedData bs = new BaseSignedData(content);
		
		Map<String,Object> parameters = new HashMap<String, Object>();
		
		//Archive time stamp is added to signature, so time stamp settings are needed.
		parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
		
		parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		parameters.put(EParameters.P_EXTERNAL_CONTENT, signable);
		
		bs.getSignerList().get(0).convert(ESignatureType.TYPE_ESA, parameters);
		
		AsnIO.dosyayaz(bs.getEncoded(), TestConstants.getDirectory() + "testdata/ESA-Converted-2.p7s");
		
		SignedDataValidationResult sdvr = ValidationUtil.validate(bs.getEncoded(), signable);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	/**
	 * Converting external signature of a huge file to ESA.
	 * @throws Exception
	 */
	public void testConvertHugeExternalContentSignature_4() throws Exception
	{
		File file = new File(movieFile);
		ISignable signable = new SignableFile(file,2048);
		
		byte [] content = AsnIO.dosyadanOKU(signatureofHugeFile);
		BaseSignedData bs = new BaseSignedData(content);
		
		Map<String,Object> parameters = new HashMap<String, Object>();
		
		//Archive time stamp is added to signature, so time stamp settings are needed.
		parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
		
		parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		parameters.put(EParameters.P_EXTERNAL_CONTENT, signable);
		
		bs.getSignerList().get(0).convert(ESignatureType.TYPE_ESA, parameters);
		
		AsnIO.dosyayaz(bs.getEncoded(), TestConstants.getDirectory() +"testdata/ESA-Converted-3.p7s");
		
		SignedDataValidationResult sdvr = ValidationUtil.validate(bs.getEncoded(), signable);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	
	/**
	 * 
	 */
	public void testConvertToESASerialSignatures() throws Exception
	{
		
		byte [] signatureFile = AsnIO.dosyadanOKU(TestConstants.getDirectory() + "testdata/counterSignatures.p7s");
		
		BaseSignedData bsd = new BaseSignedData(signatureFile);

		// To keep long years convert signatures to XLong type.
		List<Signer> allSigners = bsd.getAllSigners();
		for (Signer signer : allSigners) 
		{
			Map<String,Object> parameters = new HashMap<String, Object>();
			
			parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
			parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
			
			signer.convert(ESignatureType.TYPE_ESXLong, parameters);	
		}
		
		//It is sufficient to convert to ESA first level parallel signatures.
		List<Signer> allParallelSigners = bsd.getSignerList();
		for (Signer signer : allParallelSigners) 
		{
			Map<String,Object> parameters = new HashMap<String, Object>();
			
			//Archive time stamp is added to signature, so time stamp settings are needed.
			parameters.put(EParameters.P_TSS_INFO, TestConstants.getTSSettings());
			parameters.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
			
			signer.convert(ESignatureType.TYPE_ESA, parameters);
		}
		AsnIO.dosyayaz(bsd.getEncoded(), TestConstants.getDirectory() + "testdata/counterSignaturesESA-converted.p7s");
		
	}
	

}
